/// 核心网络请求类，类型安全、可扩展、无业务依赖
import 'package:app_core/app_core.dart';
import 'package:dio/dio.dart';
import '../common/interface/core_interface_manager.dart';
import 'http_interceptor.dart';

/// HttpManager: 单例模式，类型安全、可扩展、无业务依赖
class DioManager {
  static Dio? _dio;

  /// 获取全局唯一Dio实例
  static Dio get instance {
    _dio ??= _createDioInstance();
    return _dio!;
  }

  /// 创建 Dio 实例
  static Dio _createDioInstance() {
    final dio = Dio(_createBaseOptions());
    _addInterceptors(dio);
    return dio;
  }

  /// 创建基础配置
  static BaseOptions _createBaseOptions() {
    return BaseOptions(
      baseUrl: appGlobalConfig.netWorkConfig.baseUrl,
      connectTimeout: appGlobalConfig.netWorkConfig.connectTimeout,
      receiveTimeout: appGlobalConfig.netWorkConfig.receiveTimeout,
      headers: appGlobalConfig.netWorkConfig.headers,
    );
  }

  /// 添加拦截器
  static void _addInterceptors(Dio dio) {
    dio.interceptors.addAll([
      HttpInterceptor(), // 日志拦截器
      // 可以在这里添加更多拦截器
      // RetryInterceptor(), // 重试拦截器
      // CacheInterceptor(), // 缓存拦截器
    ]);
  }

  /// 当传了 config.baseUrl 且 path 为相对路径时，会拼接成绝对 URL；
  /// 如果 path 本身是绝对 URL（http/https），则直接用 path，忽略本次覆盖；
  /// 未传 config.baseUrl 会继续走全局环境的 BaseOptions.baseUrl
  static String _buildRequestPath(String path, RequestConfig? config) {
    String requestPath = path;
    if (config?.baseUrl != null && config!.baseUrl!.isNotEmpty) {
      final String perRequestBaseUrl = config.baseUrl!;
      final bool pathIsAbsoluteUrl = path.startsWith('http://') || path.startsWith('https://');
      if (!pathIsAbsoluteUrl) {
        final String trimmedBaseUrl = perRequestBaseUrl.endsWith('/') ? perRequestBaseUrl.substring(0, perRequestBaseUrl.length - 1) : perRequestBaseUrl;
        final String trimmedPath = path.startsWith('/') ? path.substring(1) : path;
        requestPath = '$trimmedBaseUrl/$trimmedPath';
      }
    }
    return requestPath;
  }

  /// 类型安全请求
  static Future<ApiResponse<T>> request<T>({
    required String path,
    required String method,
    Map<String, dynamic>? params,
    dynamic data,
    T Function(Map<String, dynamic>)? fromJson,
    RequestConfig? config,
    Function(int code, String? msg)? onErrorCode,
  }) async {
    try {
      final Options options = Options(method: method, headers: {...?config?.headers}, sendTimeout: config?.timeout, receiveTimeout: config?.timeout);
      final token = await CoreInterfaceManager.instance.getToken();
      /// options.headers!["Authorization"] = "Bearer $token";
      if (token != null && token.isNotEmpty) options.headers!["token"] = token;
      String requestPath = _buildRequestPath(path, config);
      final response = await instance.request(requestPath, data: data, queryParameters: params, options: options);
      return ApiResponse<T>.fromResponse(response, fromJson: fromJson, onErrorCode: onErrorCode);
    } catch (e) {
      return ApiResponse<T>.fromError(e, onErrorCode: onErrorCode);
    }
  }
}
